import {Button, List, DatePicker, NavBar, Popup, Toast, Dialog} from 'antd-mobile'
import dayjs from "dayjs";
import classNames from 'classnames'

import styles from './index.module.scss'
import {useDispatch} from "react-redux";
import {getUserProfile, updatePhoto, updateProfile} from "@/store/actions/profile";
import useInitState from "@/utils/useInitState";
import EditInput from "@/pages/Profile/Edit/components/EditInput";
import EditList from "@/pages/Profile/Edit/components/EditList";
import {useState} from "react";
import {fetchLogOut} from "@/store/actions/login";
import {useHistory} from "react-router-dom";

const Item = List.Item
export const popMap = {
  name: {
    type: 'name',
    label: '昵称'
  },
  intro: {
    type: 'intro',
    label: '简介'
  }
}

const ProfileEdit = () => {

  // 定义statehook------------------------
  // 重新定义维护昵称/简介状态的标识
  const [inputPop, setInputPop] = useState({
    type: '', // 弹层的类型/又是提交数据的字段名
    value: '', // 当弹层对应的数据
    visible: false // 弹层是否展示
  });

  /**
   * 定义维护性别和头像弹层的状态
   */
  const [listPop, setListPop] = useState({
    type: '', // 用户状态的区分
    visible: false // 控制弹层的展示标识s
  })
  const [showBirthday, setShowBirthday] = useState(false);

  //其他原生hook---------------------------
  const dispatch = useDispatch()
  const history = useHistory()

  // 自定义hook----------------------------
  const {profileInfo} = useInitState(getUserProfile, 'profile')


  // 数据获取 ----------------------------
  const {birthday, gender, intro, name, photo} = profileInfo

  // 声明事件-----------------------------
  /**
   * 让编辑昵称的弹层开启
   */
  const showEditInput = () => {
    // setInputVisible(true)
    // 点击的昵称
    setInputPop({
      type: popMap.name.type, // 弹层类型，用户提交数据时候作区分/子组件内部做不同的展示用
      value: name, // 默认值数据，子组件进行默认的展示
      visible: true // 弹层展示出来
    })
  }
  /**
   * 让编辑昵称的弹层关闭
   */
  const hideEditInput = () => {
    // setInputVisible(false)
    setInputPop({
      value: '',
      type: '',
      visible: false
    })
  }
  /**
   * 接收昵称组件更新的昵称数据
   * @param {Object} currentInfo 需要更新的用户信息对象
   * @example
   * updateName({name: '更新的昵称'})
   */
  const updateName = async (currentInfo) => {
    await dispatch(updateProfile(currentInfo))
    Toast.show({
      content: '修改成功',
      duration: 1000
    })
    // 隐藏弹层
    hideEditInput()
    hideGenderPop()
  }
  /**
   * 简介弹层展示
   */
  const showIntroInput = () => {
    // 点击简介的时候，手动修改type类型
    setInputPop({
      type: popMap.intro.type,
      value: intro,
      visible: true
    })
  }
  /**
   * 展示性别弹层
   */
  const showGenderPop = () => {
    setListPop({
      type: 'gender',
      visible: true
    })
  }

  /**
   * 关闭性别/头像弹层方法
   */
  const hideGenderPop = () => {
    setListPop({
      type: '',
      visible: false
    })
  }

  /**
   * 上传头像的方法
   */

  const changePhoto = async (fd) => {
    //提交头像的接口和其他用户信息不一致
    await dispatch(updatePhoto(fd))
    Toast.show({
      content: '上传成功',
      duration: 500
    })
    hideGenderPop()
  }

  /**
   * 点击头像展示的弹层，type='photo'
   */
  const showPhotoPop = () => {
    setListPop({
      type: 'photo',
      visible: true
    })
  }

  // 展示日期选择框
  const handleShowBirthday = () => {
    setShowBirthday(true)
  }

  const handleCloseBirthday = () => {
    setShowBirthday(false)
  }

  const updateBirthday = async value => {
    const birthday = dayjs(value).format('YYYY-MM-DD')
    await updateName({
      birthday,
    })
    // 自己的确定方法内部关闭弹层
    setShowBirthday(false)
  }

  const handleLogOut = () => {
    //  弹层
    Dialog.confirm({
      title: '温馨提示',
      content: '是否确认删除?',
      onConfirm() {
        dispatch(fetchLogOut())
        history.replace('/login')

        Toast.show({
          content: '退出成功',
          duration: 1000
        })
      }
    })
  }
  return (
    <div className={styles.root}>
      <div className="content">
        {/* 标题 */}
        <NavBar
          style={{
            '--border-bottom': '1px solid #F0F0F0'
          }}
        >
          个人信息
        </NavBar>

        <div className="wrapper">
          {/* 列表 */}
          <List className="profile-list">
            {/* 列表项 */}
            <Item
              extra={
                <span className="avatar-wrapper">
                  <img
                    width={24}
                    height={24}
                    src={photo}
                    alt=""
                  />
                </span>
              }
              onClick={showPhotoPop}
              arrow
            >
              头像
            </Item>
            <Item arrow extra={name} onClick={showEditInput}>
              昵称
            </Item>
            <Item
              arrow
              extra={
                <span className={classNames('intro', 'normal')}>
                  {intro || '未填写'}
                </span>
              }
              onClick={showIntroInput}
            >
              简介
            </Item>
          </List>

          <List className="profile-list">
            <Item onClick={showGenderPop} arrow extra={gender === '1' ? '女' : '男'}>
              性别
            </Item>
            <Item onClick={handleShowBirthday} arrow extra={birthday}>
              生日
            </Item>
          </List>

          {/* !控制了日期选择框的显示和隐藏*/}
          <DatePicker
            visible={showBirthday}
            onCancel={handleCloseBirthday}
            value={new Date(birthday)}
            title="选择年月日"
            min={new Date(1900, 0, 1, 0, 0, 0)}
            max={new Date()}
            onConfirm={updateBirthday}
          />
        </div>

        <div className="logout">
          <Button onClick={handleLogOut} className="btn" block>退出登录</Button>
        </div>
      </div>
      <Popup
        visible={inputPop.visible} // inputVisible
        position="right"
        // destroyOnClose // 关闭弹层的时候自动销毁组件
      >
        {
          /**
           * 1. TODO: 需要删除value,替换为inputPop里面的value值
           * 2. TODO: 提交数据的时候，根据类型区分字段的key(因为弹层已经进行了复用)
           * 3. TODO: 组件内部的label和文本域根据不同type（name/intro）类型做不同展示
           */
        }
        <EditInput
          onClose={hideEditInput}
          inputPop={inputPop}
          updateName={updateName}
          key={inputPop.type} // 只要type变化了的时候才去销毁组件
        />
      </Popup>

      <Popup
        visible={listPop.visible} // 弹层默认展示出来
        onMaskClick={hideGenderPop} // 点击遮罩的时候触发 ==> 关闭弹层
      >
        <EditList
          type={listPop.type}
          updateName={updateName}
          onClose={hideGenderPop}
          changePhoto={changePhoto}
        />
      </Popup>
    </div>
  )
}

export default ProfileEdit
